package com.running.base.run.jms.receiver.config;

import com.running.base.run.jms.receiver.JmsReceiver;
import com.running.base.run.jms.receiver.WeblogicSecureThreadFactoryReceive;
import com.running.base.run.jms.receiver.WeblogicSecurityBeanReceive;
import com.running.base.run.jms.receiver.WeblogicSecurityInterceptStrategyReceive;
import org.apache.camel.component.jms.JmsConfiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.support.destination.JndiDestinationResolver;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.jndi.JndiTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.Resource;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import java.util.Properties;

@Configuration
@ConditionalOnProperty(value = "jms.param", havingValue = "true")
public class JMSReceiverConfig {

    //------------------------------------

    @Value("${jms.receive.providerUrl}")
    private String jmsReceiverProviderUrl;

    @Value("${jms.receive.username}")
    private String jmsReceiverUsername;

    @Value("${jms.receive.password}")
    private String jmsReceiverPassword;

    @Value("${jms.receive.connectionFactory}")
    private String jmsReceiverConnectionFactory;

    @Value("${jms.receive.destination}")
    private String jmsReceiverDestination;


    /**
     * jms.sender.connectionFactory=ConnectionFactory-FD
     * jms.sender.destination=jn_fd_queue
     * @return
     */

    @Bean("weblogicSecurityBeanReceive")
    public WeblogicSecurityBeanReceive weblogicSecurityBeanReceive() {
        WeblogicSecurityBeanReceive weblogicSecurityBeanReceive = new WeblogicSecurityBeanReceive();
        weblogicSecurityBeanReceive.setProviderUrl(jmsReceiverProviderUrl);
        weblogicSecurityBeanReceive.setSecurityPrincipal(jmsReceiverUsername);
        weblogicSecurityBeanReceive.setSecurityCredentials(jmsReceiverPassword);
        return weblogicSecurityBeanReceive;
    }

    @Bean("weblogicThreadFactoryReceive")
    public WeblogicSecureThreadFactoryReceive weblogicSecureThreadFactoryReceive() {
        WeblogicSecureThreadFactoryReceive weblogicSecureThreadFactoryReceive = new WeblogicSecureThreadFactoryReceive();
        weblogicSecureThreadFactoryReceive.setName("jmsSubscribers");
        weblogicSecureThreadFactoryReceive.setWeblogicSecurityBeanReceive(weblogicSecurityBeanReceive());
        return weblogicSecureThreadFactoryReceive;
    }

    @Bean("jmsTaskExecutorReceive")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setBeanName("jmsTaskExecutorReceive");
        threadPoolTaskExecutor.setThreadFactory(weblogicSecureThreadFactoryReceive());
        threadPoolTaskExecutor.setCorePoolSize(1);
        threadPoolTaskExecutor.setQueueCapacity(0);
        return threadPoolTaskExecutor;
    }


    @Bean("jndiTemplateReceive")
    public JndiTemplate jndiTemplate() {
        JndiTemplate jndiTemplate = new JndiTemplate();
        Properties properties = new Properties();
        properties.setProperty("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        properties.setProperty("java.naming.provider.url", jmsReceiverProviderUrl);
        properties.setProperty("java.naming.security.principal", jmsReceiverUsername);
        properties.setProperty("java.naming.security.credentials", jmsReceiverPassword);
        jndiTemplate.setEnvironment(properties);
        return jndiTemplate;
    }

    @Bean("connectionFactoryReceive")
    public JndiObjectFactoryBean jndiObjectFactoryBean() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
        jndiObjectFactoryBean.setJndiName(jmsReceiverConnectionFactory);
        jndiObjectFactoryBean.setExposeAccessContext(true);
        jndiObjectFactoryBean.setLookupOnStartup(false);
        jndiObjectFactoryBean.setProxyInterface(ConnectionFactory.class);
        return jndiObjectFactoryBean;
    }

    @Bean("jmsDestinationResolverReceive")
    public JndiDestinationResolver jndiDestinationResolver() {
        JndiDestinationResolver jndiDestinationResolver = new JndiDestinationResolver();
        jndiDestinationResolver.setJndiTemplate(jndiTemplate());
        return jndiDestinationResolver;
    }


    @Bean("jmsTemplateReceive")
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory((ConnectionFactory) jndiObjectFactoryBean().getObject());
        jmsTemplate.setDestinationResolver(jndiDestinationResolver());
        return jmsTemplate;
    }

    @Bean("jmsDestinationReceive")
    public JndiObjectFactoryBean jndiObjectFactoryQueueBean() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
        jndiObjectFactoryBean.setJndiName(jmsReceiverDestination);
        return jndiObjectFactoryBean;
    }

    @Resource
    private JmsReceiver jmsReceiver;

    @Bean("simpleMessageListener")
    public DefaultMessageListenerContainer defaultMessageListenerContainer() {
        DefaultMessageListenerContainer defaultMessageListenerContainer = new DefaultMessageListenerContainer();
        defaultMessageListenerContainer.setConcurrentConsumers(1);
        defaultMessageListenerContainer.setConnectionFactory((ConnectionFactory) jndiObjectFactoryBean().getObject());
        defaultMessageListenerContainer.setDestination((Destination) jndiObjectFactoryQueueBean().getObject());
        defaultMessageListenerContainer.setMessageListener(jmsReceiver);
        defaultMessageListenerContainer.setTaskExecutor(threadPoolTaskExecutor());
        defaultMessageListenerContainer.setAutoStartup(true);
        return defaultMessageListenerContainer;
    }

    @Bean("jmsConfigReceive")
    public JmsConfiguration jmsConfiguration() {
        JmsConfiguration jmsConfiguration = new JmsConfiguration();
        jmsConfiguration.setConnectionFactory((ConnectionFactory) jndiObjectFactoryBean().getObject());
        jmsConfiguration.setDestinationResolver(jndiDestinationResolver());
        jmsConfiguration.setTaskExecutor(threadPoolTaskExecutor());
        jmsConfiguration.setConcurrentConsumers(1);
        return jmsConfiguration;
    }

    @Bean("jmsInterceptStrategyReceive")
    public WeblogicSecurityInterceptStrategyReceive weblogicSecurityInterceptStrategyReceive() {
        WeblogicSecurityInterceptStrategyReceive weblogicSecurityInterceptStrategyReceive = new WeblogicSecurityInterceptStrategyReceive();
        weblogicSecurityInterceptStrategyReceive.setWeblogicSecurityBeanReceive(weblogicSecurityBeanReceive());
        return weblogicSecurityInterceptStrategyReceive;
    }


}